package com.example.bookstore.service

import com.example.bookstore.dao.UserDao
import com.example.bookstore.entity.CartDetailEntity
import com.example.bookstore.entity.UserEntity
import com.example.bookstore.exception.*
import com.example.bookstore.security.JwtUser
import com.example.bookstore.validate.UserUpdateRestrict
import com.fasterxml.jackson.module.kotlin.readValue
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.stereotype.Service

/**
 * Created by IntelliJ IDEA.
 * User: lvshe
 * Date: 2019/8/10
 * Time: 15:10
 */
@Service
class UserService : BaseService<UserDao, UserEntity>() {

    @Autowired
    private lateinit var bookService: BookService
    @Autowired
    private lateinit var cartService: CartService
    @Autowired
    private lateinit var cartDetailService: CartDetailService


    fun getTokenUser(): UserEntity {
//        return this.getAllPageable(0, 1).first()
        val authentication = SecurityContextHolder.getContext().authentication
                ?: throw LogException("无法获取认证信息，确认调用方法路径配置认证信息")
        val jwtUser = authentication.principal as JwtUser
        return findByEmailOrNull(jwtUser.username) ?: throw TokenException("从 token 用户信息出错")
    }

    override fun updateWithJson(id: String, json: String): UserEntity {
        val user = getTokenUser()
        if (user.id != id) throw AccessDeniedException("没有权限更新其他ID的用户信息")
        val jsonFormat = objectMapper.readValue<UserUpdateRestrict>(json)
        return updateUserInfo(jsonFormat)
    }

    fun updateUserInfo(UserUpdate: UserUpdateRestrict): UserEntity {
        val user = getTokenUser()
        val readValue = objectMapper.readerForUpdating(user).readValue<UserEntity>(objectMapper.writeValueAsString(UserUpdate))
        return save(readValue)
    }

    fun addToCart(bookId: String) {
        val book = bookService.getById(bookId)
        val cart = getTokenUser().cart
        val cartDetail = cartDetailService.getByBookAndCartOrNull(book, cart)
        if (cartDetail == null) {
            cartDetailService.save(CartDetailEntity(cart, 1, book))
        } else {
            cartDetail.number++
            cartDetailService.update(cartDetail)
        }
    }

    fun getCartList(): Set<CartDetailEntity> {
        return getTokenUser().cart.cartDetails
    }

    fun clearCart() {
        return cartDetailService.deleteAll(getTokenUser().cart.cartDetails.toMutableList())
    }

    fun deleteCartItemById(id: String) {
        val cartItem = cartDetailService.getById(id)
        if (cartItem.cart.user != getTokenUser()) throw AccessDeniedException()
        cartDetailService.deleteById(id)
    }

    fun findByEmailOrNull(email: String): UserEntity? {
        return dao.findByEmail(email)
    }

    fun registerUser(user: UserEntity): UserEntity {
        if (!user.id.isBlank()) throw SecurityException("注册禁止传入用户ID")
        if (findByEmailOrNull(user.email) != null) throw ParamsValidateException("该邮箱已存在")
        return this.save(user)
    }

}